//
//  YQMapRoutesViewController.swift
//  Cycling
//
//  Created by CSS on 3/29/23.
//

import UIKit

import Mapbox
import MapboxDirections
import MapboxNavigation
import MapboxCoreNavigation
import CoreLocation
import MapboxMaps

class YQMapRoutesViewController: BaseViewController {

    @IBOutlet weak var contentStackView: UIStackView!
    @IBOutlet weak var bottomContentStackView: UIStackView!
    
    //中间变量
    private var selectRoute: Route?
    private var routeOptions: NavigationRouteOptions?
    
    lazy private var navigationMapView: NavigationMapView = {
        let mapView: NavigationMapView = .init(frame: view.bounds)
        
        mapView.routeCasingColor = .color(withHexString: "#0FDAB2")
        mapView.trafficUnknownColor = .color(withHexString: "#0FDAB2")
        
        let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(longGestureReceive(_:)))
        longGesture.minimumPressDuration = 2
        mapView.addGestureRecognizer(longGesture)
        
        if fromLocation == nil {
            mapView.mapView.location.addLocationConsumer(newConsumer: self)
        }
        
        return mapView
    }()
    lazy private var routeSelectView: CSRouteSelectView = {
        let routeSelectView: CSRouteSelectView = .forAutoLayout()
        
        routeSelectView.goNavigationBlock = { [weak self]in
            self?.goToNavigation(withRoute: $0, routeOptions: $1)
        }
        routeSelectView.willChangeRoutesBlock = { [weak self] in
            self?.reloadRoutes(withRoutes: $0, selectRoute: $1)
        }
        routeSelectView.requestFailedRoutes = { [weak self] in
            self?.showHudTipStr("暂无路线")
            self?.navigationController?.popViewController(animated: true)
        }
        
        return routeSelectView
    }()
    
    private var navigationService: CSNavigationService?
    private var systemNavigationService: CSSystemRouteNavigationService?
    
    public var fromLocation: CLLocationCoordinate2D?
    public var endLocation: CLLocationCoordinate2D?
    @objc public var didEndNavigationBlock: ((Int) -> Void)?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        contentStackView.addArrangedSubview(navigationMapView)
        
        reloadRouteSelectView()
    }
    
    // MARK: 事件处理方法
    @IBAction private func beginButtonAction(_ sender: Any) {
//        guard let selectRoute = selectRoute, let routeOptions = routeOptions else {
//            return
//        }
        /*
        let navigationService = MapboxNavigationService(route: selectRoute, routeIndex: 0, routeOptions: routeOptions, directions: .none, locationSource: .none, eventsManagerType: .none, simulating: .always, routerType: .none)
        
        let topBannerVC = CSNavigationTopBannerViewController()
        let bottomBannerView = CSNavigationBottomBannerViewController()
        
        topBannerVC.topActionBlock = { [weak self] type in
            guard let self = self else {
                return
            }
            if type == 0 {
                navigationService.endNavigation()
                self.presentedViewController?.dismiss(animated: true)
            }
        }
        
        bottomBannerView.bannerActionTypeBlock = { [weak self]type in
            if type == 0 {
                self?.presentedViewController?.dismiss(animated: true)
            }
        }
        bottomBannerView.navigationService = navigationService
        
        let navigationOptions = NavigationOptions(navigationService: navigationService, topBanner: topBannerVC, bottomBanner: bottomBannerView)
        let navigationVC = NavigationViewController(for: selectRoute, routeIndex: 0, routeOptions: routeOptions, navigationOptions: navigationOptions)
        
        navigationVC.mapView?.routeCasingColor = .color(withHexString: "#0FDAB2")
        navigationVC.mapView?.trafficUnknownColor = .color(withHexString: "#0FDAB2")
        navigationVC.mapView?.traversedRouteColor = .color(withHexString: "#808080")
        navigationVC.routeLineTracksTraversal = true
                
        navigationVC.modalPresentationStyle = .fullScreen
        present(navigationVC, animated: true)
        */
    }
    
    @objc private func longGestureReceive(_ sender: UILongPressGestureRecognizer) {
        let locationPoint = navigationMapView.mapView.mapboxMap.coordinate(for: sender.location(in: navigationMapView))
        endLocation = locationPoint
        reloadRouteSelectView()
    }
    
}

// MARK: 获取当前点坐标位置
extension YQMapRoutesViewController: LocationConsumer {
    
    func locationUpdate(newLocation: Location) {
        if fromLocation == nil {
            fromLocation = newLocation.coordinate
            reloadRouteSelectView()
        }
        navigationMapView.mapView.location.removeLocationConsumer(consumer: self)
    }
    
}

// MARK: NavigationMapView委托处理类
extension YQMapRoutesViewController: MGLMapViewDelegate {
    
    func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
        mapView.showsUserLocation = false
        mapView.userTrackingMode = .none
    }
    
    func mapViewDidFailLoadingMap(_ mapView: MGLMapView, withError error: Error) {
        mapView.showsUserLocation = false
        mapView.userTrackingMode = .none
    }
    
}

// MARK: 对外访问类
extension YQMapRoutesViewController {
    
    @objc func setupLocations(withFromLocation fromLocation: CLLocationCoordinate2D, endLocation: CLLocationCoordinate2D) {
        self.fromLocation = fromLocation
        self.endLocation = endLocation
        
        let origin = Waypoint(coordinate: fromLocation, name: "起始位置")
        let destination = Waypoint(coordinate: endLocation, name: "终点位置")
        
        let routeOptions = NavigationRouteOptions(waypoints: [origin, destination], profileIdentifier: .cycling)
        self.routeOptions = routeOptions
        
        Directions.shared.calculate(routeOptions) { session, result in
            switch result {
            case .failure(let error):
                print(error.localizedDescription)
            case .success(let response):
                // Pass the first generated route to the the NavigationViewController
                guard let routes = response.routes, routes.count > 0 else {
                    return
                }
                /*
                self.navigationMapView.show(routes)
                self.navigationMapView.showWaypoints(on: routes[0])
                self.selectRoute = routes.first
                let coordinators = routes.reduce(into: []) { partialResult, route in
                    if let lineString = route.shape, lineString.coordinates.count > 0 {
                        partialResult.append(contentsOf: lineString.coordinates)
                    }
                } as? [CLLocationCoordinate2D] ?? []
                let shapeLine = MGLPolyline(coordinates: coordinators, count: UInt(coordinators.count))
                let camera = self.navigationMapView.cameraThatFitsShape(shapeLine, direction: 0, edgePadding: .init(top: 30, left: 30, bottom: 30, right: 30))
                self.navigationMapView.setUserTrackingMode(.none, animated: true, completionHandler: nil)
                self.navigationMapView.setCamera(camera, animated: true)
                 */
            }
        }
    }
    
    @objc func endLocationSetup(withLat lat: CLLocationDistance, lng: CLLocationDistance) {
        endLocation = .init(latitude: lat, longitude: lng)
    }
    
}

// MARK: 工具类方法(UI更新)
private extension YQMapRoutesViewController {
    
    func reloadRoutes(withRoutes routes:[Route]?, selectRoute: Route?) {
        if routes == nil && selectRoute == nil {
            navigationMapView.removeRoutes()
            return
        }
        if let routes = routes {
            navigationMapView.showcase(routes, routesPresentationStyle: .all(shouldFit: true))
        }
        if let selectRoute = selectRoute {
            navigationMapView.showWaypoints(on: selectRoute)
        }
//        navigationMapView.mapView.mapboxMap.setCamera(to: .overviewMobileCamera)
    }
    
    func goToNavigation(withRoute route: IndexedRouteResponse, routeOptions: RouteOptions?) {
//        navigationService = .showMapNavigation(withIndexRouteResponse: route, presentingVC: self)
        systemNavigationService = .showMapNavigation(withIndexRouteResponse: route, presentingVC: self)
        systemNavigationService?.endNavigationBlock = {
            self.navigationController?.popViewController(animated: true)
            self.didEndNavigationBlock?(0)
        }
    }
    
    func reloadRouteSelectView() {
        guard let fromLocation = fromLocation, let endLocation = endLocation else {
            return
        }
        if routeSelectView.superview == nil {
            bottomContentStackView.addArrangedSubview(routeSelectView)
        }
        routeSelectView.reload(withStartPoint: fromLocation, toPoint: endLocation)
    }
    
}
